package com.twu.biblioteca.session;

import com.twu.biblioteca.Customer;
import com.twu.biblioteca.Library;
import com.twu.biblioteca.session.actions.*;
import com.twu.biblioteca.view.UI;

import java.util.ArrayList;
import java.util.List;

public class Session {

    private final Library library;
    private final UI ui;
    private final List<SessionAction> actions;
    private Customer currentlyLoggedIn;
    private boolean running;

    public Session(Library library, UI ui) {
        this.running= false;
        this.library = library;
        this.ui = ui;
        actions = new ArrayList<>();
        createActions();
    }

    /**
     * XXX Could use reflection to load package
     */
    private void createActions() {
        actions.add(new ListBooksAction(SessionOption.LIST_BOOK, this));
        actions.add(new CheckoutBookAction(SessionOption.CHECKOUT_BOOK, this));
        actions.add(new ReturnBookAction(SessionOption.RETURN_BOOK,this));
        actions.add(new ListMoviesAction(SessionOption.LIST_MOVIE, this));
        actions.add(new CheckoutMovieAction(SessionOption.CHECKOUT_MOVIE, this));
        actions.add(new ReturnMovieAction(SessionOption.RETURN_MOVIE, this));
        actions.add(new ViewDetailsAction(SessionOption.VIEW_DETAILS, this));
        actions.add(new LoginAction(SessionOption.LOGIN, this));
        actions.add(new QuitAction(SessionOption.QUIT, this));
    }

    public void printOptions() {
        ui.showOptions(this.isCurrentlyLoggedIn());
    }

    public boolean isCurrentlyLoggedIn() {
        return currentlyLoggedIn!= null;
    }

    public SessionOption getOption() {
        String line = this.getUi().readInput();
        for (SessionOption option : SessionOption.values()) {
            if (option.getKey().equalsIgnoreCase(line) && option.isNeedLogin() == isCurrentlyLoggedIn())
                return option;
        }
        ui.invalidOptionEntered();
        return null;
    }

    public void selectOption(SessionOption option) {
        for(SessionAction action:actions){
            if(action.getOption().equals(option))
                action.performAction(action.getActionInput());
        }
    }

    public Customer getCurrentlyLoggedIn() {
        return currentlyLoggedIn;
    }

    public Library getLibrary() {
        return library;
    }

    public void setCurrentlyLoggedIn(Customer currentlyLoggedIn) {
        this.currentlyLoggedIn = currentlyLoggedIn;
    }

    public UI getUi() {
        return ui;
    }

    public void quit() {
        this.getUi().quit();
        this.running = false;
    }

    public void run() {
        ui.welcomeMessage();
        printOptions();
        running = true;
        while (running) {
            SessionOption selected = this.getOption();
            if (selected != null)
                this.selectOption(selected);
        }
    }
}
